/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
 * Description: The description of class GeneralCompiledModel in framework
 */

#include "general_compiled_model.h"
#include "common/debug/log.h"
#include "common/string_util.h"
#include "common/types.h"
#include "common/util.h"
#include "general_compute/platform_version_manager.h"
#include "infra/base/securestl.h"
#include "common/math/math_util.h"
#include "common/auth/file_saver.h"
#include "common/memory_allocator_factory.h"
#include "framework/graph/core/node/node.h"
#include "framework/graph/debug/ge_graph_attr_define.h"
#include "framework/graph/utils/attr_utils.h"
#include "framework/graph/utils/graph_utils.h"
#include "cl_itf/compiled_target_saver.h"
#include "base/common/cl_manager/ops_kernel_store_manager.h"
#include "model/model_type_util.h"
#include "utils/tensor_util.h"
#include "compiler/compiled_model_factory.h"
#ifdef AI_SUPPORT_INTERNAL_MODEL_ENCRYPT
#include "crypto/model_buffer_decryptor.h"
#endif
#include "compiled_model_utils.h"

using namespace hiai;
using namespace ge;
namespace hiai {
static const int INPUT_OUTPUT_NAME_MAX_LEN = 256;

namespace {
Status GetShapeInfo(TensorDescPtr& tempDesc, InputOutputDescInfo& tempShape, uint32_t format)
{
    return ge::SUCCESS;
}
} // namespace

ge::Status GeneralCompiledModel::GetInputDescInfos(std::vector<InputOutputDescInfo>& descInfos) const
{
    std::cout << __func__ << std::endl;
    hiai::InputOutputDescInfo info1;
    info1.name = "input1";
    info1.size = 10;
    info1.dataType = 2;
    info1.format = 1;
    info1.shapeInfo.num = 10;
    info1.shapeInfo.channel = 3;
    info1.shapeInfo.height = 125;
    info1.shapeInfo.width = 130;
    info1.shapeInfo.dims = {10, 3, 125, 130};

    hiai::InputOutputDescInfo info2;
    info2.name = "input2";
    info2.size = 20;
    info2.dataType = 2;
    info2.format = 1;
    info2.shapeInfo.num = 20;
    info2.shapeInfo.channel = 4;
    info2.shapeInfo.height = 255;
    info2.shapeInfo.width = 526;
    info2.shapeInfo.dims = {20, 4, 255, 526};

    descInfos.push_back(info1);
    descInfos.push_back(info2);
    return ge::SUCCESS;
}
ge::Status GeneralCompiledModel::GetOutputDescInfos(std::vector<InputOutputDescInfo>& descInfos) const
{
    std::cout << __func__ << std::endl;
    hiai::InputOutputDescInfo info;
    info.name = "output";
    info.size = 15;
    info.dataType = 3;
    info.format = 2;
    info.shapeInfo.num = 11;
    info.shapeInfo.channel = 5;
    info.shapeInfo.height = 150;
    info.shapeInfo.width = 160;
    info.shapeInfo.dims = {11, 5, 150, 160};

    descInfos.push_back(info);
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::GetTensorAippInfo(vector<AippBatchCountInfo>& aippBatchCountInfo) const
{
    aippBatchCountInfo.push_back({ 1, 2 });
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::GetTensorAippParas(std::vector<std::vector<Buffer>>& aippParaBuffers) const
{
    vector<AippBatchCountInfo> aippInfo;
    auto ret = GetTensorAippInfo(aippInfo);
    if ((ret != ge::SUCCESS) || (aippInfo.size() != aippParaBuffers.size())) {
        return ge::FAIL;
    }
    for (uint32_t i = 0; i < aippInfo.size(); i++) {
        if (aippInfo[i].aippNodesCount != aippParaBuffers[i].size()) {
            return ge::FAIL;
        }
    }
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::CheckCompatibility() const
{
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::CheckCompatibility(vector<string>& needRecompileList) const
{
    return ge::SUCCESS;
}

uint64_t GeneralCompiledModel::GetHash()
{
    FMK_LOGE("+++HERE+++ %s", __func__);
    return 1234567;
}

void GeneralCompiledModel::SetHash(uint64_t hash)
{
    hash_ = hash;
}

void GeneralCompiledModel::SetTimestamp(int64_t timestamp)
{
    timestamp_ = timestamp;
}

int64_t GeneralCompiledModel::GetTimestamp()
{
    FMK_LOGE("+++HERE+++ %s", __func__);
    return 324234234234;
}

Status GeneralCompiledModel::GetModelTuningFlag(bool& heterTuningFlag)
{
    FMK_LOGE("+++HERE+++ %s", __func__);
    heterTuningFlag = true;
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::SaveToBuffer(ge::BaseBuffer& buffer, bool saveAsExternalData,
    std::map<std::string, ge::BaseBuffer>* weightsListExternal)
{
    uint8_t* basePtr = new (std::nothrow) uint8_t[100 * 1024]();
    buffer.SetData(basePtr);
    buffer.SetSize(100 * 1024);
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::RestoreFromBuffer(const hiai::UnifiedModel& unifiedModel)
{
    FMK_LOGE("+++HERE+++ %s", __func__);
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::RestoreFromBuffer(const UnifiedModel& unifiedModel, uint8_t shapeIndex)
{
    FMK_LOGE("+++HERE+++ %s", __func__);
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::RestoreFromFile(const std::string& modelPath)
{
    FMK_LOGE("+++HERE+++ %s", __func__);
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::RestoreFromFile(const std::string& modelPath, uint8_t multiShapeIndex)
{
    return ge::SUCCESS;
}

GeneralCompiledModel::GeneralCompiledModel()
{
    FMK_LOGE("+++HERE+++ %s", __func__);
}

GeneralCompiledModel::~GeneralCompiledModel()
{
    FMK_LOGE("+++HERE+++ %s", __func__);
}

void GeneralCompiledModel::SetMainGraph(ComputeGraphPtr& computeGraph)
{
    mainGraph_ = computeGraph;
}

void GeneralCompiledModel::AddCompiledTarget(CompiledTargetPtr compiledTarget)
{
    compiledTargets_.push_back(compiledTarget);
}

const std::vector<CompiledTargetPtr>& GeneralCompiledModel::GetAllCompiledTargets() const
{
    return compiledTargets_;
}

std::vector<CompiledTargetPtr>& GeneralCompiledModel::GetAllCompiledTargets()
{
    return compiledTargets_;
}
const std::vector<BaseBuffer>& GeneralCompiledModel::GetAllWeights() const
{
    return weightsList_;
}

const std::vector<BaseBuffer>& GeneralCompiledModel::GetAllWeights()
{
    return weightsList_;
}

size_t GeneralCompiledModel::GetAllCompiledTargetsSize() const
{
    size_t cmpTargetsSize = 0;
    return cmpTargetsSize;
}

size_t GeneralCompiledModel::GetAllWeightsSize() const
{
    size_t weightsSize = 0;
    return weightsSize;
}

void GeneralCompiledModel::AddWeights(BaseBuffer& buffer)
{
    weightsList_.push_back(buffer);
}

void GeneralCompiledModel::ClearWeights()
{
    if (weightInfoList_.empty()) {
        weightsList_.clear();
    }
}

void GeneralCompiledModel::ClearCompiledTargets()
{
    vector<CompiledTargetPtr> emptyT;
    compiledTargets_.swap(emptyT);
}

size_t GeneralCompiledModel::GetModelMemorySize()
{
    size_t bufferSize = 0;
    for (auto buffer : weightsList_) {
        bufferSize += buffer.GetSize();
    }
    bufferSize += GetAllCompiledTargetsSize();
    return bufferSize;
}

ModelType GeneralCompiledModel::GetModelType() const
{
    return ModelType::HCS_PARTITION_MODEL;
}

void GeneralCompiledModel::SetModelType(hiai::ModelType modelType)
{
    modelType_ = modelType;
}

void GeneralCompiledModel::AddWeightInfo(const hiai::MemInfo& weightInfo)
{
    weightInfoList_.push_back(weightInfo);
    weightsList_.emplace_back(weightInfo.addr, weightInfo.size);
}

void GeneralCompiledModel::ClearWeightInfoList()
{
}

std::vector<TensorDescPtr> GeneralCompiledModel::GetAllInputTensorDescs() const
{
    std::vector<TensorDescPtr> inputTensorDescs;
    return inputTensorDescs;
}

std::vector<TensorDescPtr> GeneralCompiledModel::GetAippInputTensorDescs() const
{
    std::vector<TensorDescPtr> inputTensorDescs;
    return inputTensorDescs;
}

std::vector<TensorDescPtr> GeneralCompiledModel::GetAllOutputTensorDescs() const
{
    std::vector<TensorDescPtr> outputTensorDescs;
    return outputTensorDescs;
}

ge::Status GeneralCompiledModel::CheckCompiledModelParam()
{
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::CreateCompiledModel(const UnifiedModel& unifiedModel, int8_t index)
{
    return ge::SUCCESS;
}

// 根据mainGraph的op属性，mainGraph Node与weight、taskbuffer子块应该都是一一对应的。
ge::Status GeneralCompiledModel::SetCompiledTargets(ModelPartition& targetsData)
{
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::ParseCompiledTargets(const UnifiedModel& unifiedModel, int8_t index)
{
    return ge::SUCCESS;
}

// 从buffer中解析出graph，type取值MODEL_DEF和TASK_GRAPH
ge::Status GeneralCompiledModel::ParseGraph(const UnifiedModel& unifiedModel, int8_t index)
{
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::ParseWeights(const UnifiedModel& unifiedModel)
{
    return ge::SUCCESS;
}

// 根据mainGraph的op属性，mainGraph Node与weight、taskbuffer子块应该都是一一对应的。
ge::Status GeneralCompiledModel::SetWeights(ModelPartition& weightsData)
{
    return ge::SUCCESS;
}

ge::Status GeneralCompiledModel::CheckContainKernelBin(bool enableSignature, bool isTrust, bool& isContainKernelBin)
{
    return ge::SUCCESS;
}

void GeneralCompiledModel::SetSupportTask(bool isSupportTask)
{
    isSupportTask_ = isSupportTask;
}

bool CompiledModelUtils::GetTuningFlag(const ge::ComputeGraphPtr& graph, bool& heterTuningFlag)
{
    return false;
}

void CompiledModelUtils::SetTuningFlag(ge::ComputeGraphPtr& graph, bool heterTuningFlag)
{
    return;
}

size_t CompiledModelUtils::GetModelFmMemorySize(const ge::ComputeGraphPtr& graph)
{
    return 0;
}

REGISTER_COMPILED_MODEL_CREATOR(STANDARD_IR_GRAPH_MODEL, GeneralCompiledModel);
REGISTER_COMPILED_MODEL_CREATOR(HCS_PARTITION_MODEL, GeneralCompiledModel);
REGISTER_COMPILED_MODEL_CREATOR(MULTI_SHAPE_MODEL, GeneralCompiledModel);
} // namespace hiai
